/*
 * @Author: ZhanXie
 * @Date: 2020-05-11 09:11:21
 * @LastEditors: ZhanXie
 * @LastEditTime: 2020-10-25 11:05:36
 * @Description: 
 * @FilePath: /projectStudy/mini-redux/src/mini-redux.js
 */
export function createStore(reducer, enhancer) {
  if (enhancer) {
    /* 
      对createStore进行扩展
      依然是返回{getState,dispatch,subscribe},但dispatch是进行过增强器包装的
    */
    return enhancer(createStore)(reducer)
  }
  let state = {}
  let listeners = []

  /* 获取当前state */
  function getState() {
    return state
  }
  /* 传入action通过reducer规则返回新的state */
  function dispatch(action) {
    state = reducer(state, action)
    listeners.forEach(v => v())
    return action
  }
  /* 做订阅，每次dispatch之后执行订阅里面的所有函数 */
  function subscribe(listener) {
    listeners.push(listener)
  }
  /* 初始化 */
  dispatch({ type: '@@INIT-MINI-REDUX' })
  return { getState, dispatch, subscribe }
}
export function applyMiddleware(...middlewares /* 多个中间件 */) {
  return createStore => (...args) => {
    const store = createStore(...args) // 返回{getState, dispatch, subscribe}
    let dispatch = store.dispatch

    // 中间件的接口
    const midApi = {
      getState: store.getState,
      dispatch: (...args) => dispatch(...args)
    }
    const middlewareChain = middlewares.map(middleware => middleware(midApi))
    dispatch = compose(...middlewareChain)(store.dispatch)

    //dispatch = middleware(midApi)(store.dispatch)
    createStore = null
    return {
      ...store, //将store对象展开
      dispatch //将dispatch覆盖store.dispatch
    }
  }
}
// fn1(fn2(fn3))
export function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  } else if (funcs.length === 1) {
    return funcs[0]
  } else {
    return funcs.reduce((ret, item) => (...args) => ret(item(...args)))
  }
}

export function bindActionCreators(creators, dispatch) {
  let bound = {}
  Object.keys(creators).forEach(v => {
    bound[v] = (...args) => dispatch(creators[v](...args))
  })
  return bound
}